#include "stdafx.h"
#include "stream/StreamCopier.hpp"
#include "stream/buffer.hpp"

STREAM_NAMESPACE_BEGIN

std::streamsize CStreamCopier::copyStream(std::istream& istr, std::ostream& ostr, std::size_t bufferSize)
{
	jh_assert (bufferSize > 0);

	TBuffer<char> buffer(bufferSize);
	std::streamsize len = 0;
	istr.read(buffer.begin(), bufferSize);
	std::streamsize n = istr.gcount();
	while (n > 0)
	{
		len += n;
		ostr.write(buffer.begin(), n);
		if (istr && ostr)
		{
			istr.read(buffer.begin(), bufferSize);
			n = istr.gcount();
		}
		else n = 0;
	}
	return len;
}

std::streamsize CStreamCopier::copyToString(std::istream& istr, std::string& str, std::size_t bufferSize)
{
	jh_assert (bufferSize > 0);

	TBuffer<char> buffer(bufferSize);
	std::streamsize len = 0;
	istr.read(buffer.begin(), bufferSize);
	std::streamsize n = istr.gcount();
	while (n > 0)
	{
		len += n;
		str.append(buffer.begin(), static_cast<std::string::size_type>(n));
		if (istr)
		{
			istr.read(buffer.begin(), bufferSize);
			n = istr.gcount();
		}
		else n = 0;
	}
	return len;
}

std::streamsize CStreamCopier::copyStreamUnbuffered(std::istream& istr, std::ostream& ostr)
{
	char c;
	std::streamsize len = 0;
	istr.get(c);
	while (istr && ostr)
	{
		++len;
		ostr.put(c);
		istr.get(c);
	}
	return len;
}


#if defined(JH_HAVE_INT64)

UInt64 CStreamCopier::copyStream64(std::istream& istr, std::ostream& ostr, std::size_t bufferSize)
{
	jh_assert (bufferSize > 0);

	TBuffer<char> buffer(bufferSize);
	UInt64 len = 0;
	istr.read(buffer.begin(), bufferSize);
	std::streamsize n = istr.gcount();
	while (n > 0)
	{
		len += n;
		ostr.write(buffer.begin(), n);
		if (istr && ostr)
		{
			istr.read(buffer.begin(), bufferSize);
			n = istr.gcount();
		}
		else n = 0;
	}
	return len;
}

UInt64 CStreamCopier::copyToString64(std::istream& istr, std::string& str, std::size_t bufferSize)
{
	jh_assert (bufferSize > 0);

	TBuffer<char> buffer(bufferSize);
	UInt64 len = 0;
	istr.read(buffer.begin(), bufferSize);
	std::streamsize n = istr.gcount();
	while (n > 0)
	{
		len += n;
		str.append(buffer.begin(), static_cast<std::string::size_type>(n));
		if (istr)
		{
			istr.read(buffer.begin(), bufferSize);
			n = istr.gcount();
		}
		else n = 0;
	}
	return len;
}

UInt64 CStreamCopier::copyStreamUnbuffered64(std::istream& istr, std::ostream& ostr)
{
	char c;
	UInt64 len = 0;
	istr.get(c);
	while (istr && ostr)
	{
		++len;
		ostr.put(c);
		istr.get(c);
	}
	return len;
}
#endif

STREAM_NAMESPACE_END
